#!/usr/bin/env python3
"""
Event Processor - 事件处理器（本地测试版本）
从Kinesis读取浏览器事件，使用规则引擎或LLM分析用户行为，存储到PostgreSQL

这是本地开发/测试入口，生产环境请使用 lambda_handler.py
"""

import json
import time
import os
import logging
from typing import Dict, Any
import boto3

# 导入核心模块（与 Lambda 共享）
from core import BehaviorAnalyzer
from database import PostgresWriter

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

# 环境变量配置
AWS_ENDPOINT = os.getenv('AWS_ENDPOINT', 'http://localstack:4566')
AWS_REGION = os.getenv('AWS_REGION', 'us-east-1')
KINESIS_STREAM_NAME = os.getenv('KINESIS_STREAM_NAME', 'click-events-stream')


class KinesisConsumer:
    """Kinesis消费者（本地轮询模式）"""

    def __init__(self):
        self.kinesis_client = boto3.client(
            'kinesis',
            endpoint_url=AWS_ENDPOINT,
            region_name=AWS_REGION,
            aws_access_key_id='test',
            aws_secret_access_key='test'
        )
        self.stream_name = KINESIS_STREAM_NAME
        self.shard_iterator = None

    def initialize(self):
        """初始化Shard Iterator"""
        try:
            response = self.kinesis_client.get_shard_iterator(
                StreamName=self.stream_name,
                ShardId='shardId-000000000000',
                ShardIteratorType='LATEST'  # 从最新位置开始读取
            )
            self.shard_iterator = response['ShardIterator']
            logger.info(f"✅ 成功连接到Kinesis流: {self.stream_name}")
        except Exception as e:
            logger.error(f"❌ 连接Kinesis失败: {e}")
            raise

    def get_records(self) -> list:
        """获取记录（支持任意格式）"""
        try:
            response = self.kinesis_client.get_records(
                ShardIterator=self.shard_iterator,
                Limit=10  # 每次最多读取10条
            )

            # 更新iterator
            self.shard_iterator = response['NextShardIterator']

            # 解析记录
            records = []
            for record in response['Records']:
                try:
                    raw_data = record['Data']

                    # 确保是字符串格式
                    if isinstance(raw_data, bytes):
                        raw_data = raw_data.decode('utf-8')

                    # 尝试解析JSON
                    try:
                        data = json.loads(raw_data)
                        # 如果解析成功，检查是否是合法的事件数据
                        if not isinstance(data, dict):
                            # 如果不是字典，包装它
                            data = {
                                'raw_message': str(data),
                                'userId': 'unknown',
                                'eventType': 'raw_text'
                            }
                    except (json.JSONDecodeError, ValueError) as e:
                        # JSON解析失败，包装成字典交给LLM处理
                        logger.info(f"收到非JSON格式数据，包装后交给LLM处理")
                        data = {
                            'raw_message': raw_data,
                            'userId': 'unknown',
                            'eventType': 'raw_text'
                        }

                    records.append({
                        'data': data,
                        'sequence_number': record['SequenceNumber'],
                        'arrival_time': record['ApproximateArrivalTimestamp']
                    })

                except Exception as e:
                    logger.error(f"处理单条记录失败: {e}，跳过此记录")
                    continue

            return records

        except Exception as e:
            logger.error(f"❌ 读取Kinesis记录失败: {e}")
            return []


class EventProcessor:
    """Event Processor处理器（主流程）"""

    def __init__(self):
        self.consumer = KinesisConsumer()
        self.analyzer = BehaviorAnalyzer()  # 使用核心模块
        self.writer = PostgresWriter()      # 使用核心模块
        self.running = False

    def start(self):
        """启动处理"""
        logger.info("🚀 Event Processor 启动中...")

        # 初始化组件
        self.consumer.initialize()
        self.writer.connect()

        self.running = True
        logger.info("✅ Event Processor 已启动，开始处理数据...")

        try:
            self._process_loop()
        except KeyboardInterrupt:
            logger.info("⏸️  收到停止信号")
        finally:
            self.stop()

    def _process_loop(self):
        """主处理循环"""
        empty_count = 0

        while self.running:
            # 从Kinesis读取记录
            records = self.consumer.get_records()

            if records:
                empty_count = 0
                logger.info(f"📦 收到 {len(records)} 条记录")

                for record in records:
                    self._process_record(record)
            else:
                empty_count += 1
                if empty_count == 1:
                    logger.info("💤 等待新数据...")

                # 等待1秒再继续
                time.sleep(1)

    def _process_record(self, record: Dict[str, Any]):
        """处理单条记录"""
        try:
            event_data = record['data']

            # 使用核心模块分析用户行为
            analysis_result = self.analyzer.analyze(event_data)

            # 写入PostgreSQL
            self.writer.write_behavior(event_data, analysis_result)

            logger.info(
                f"✨ 处理完成: {event_data.get('userId')} - "
                f"{analysis_result['behavior_type']} - "
                f"{analysis_result['behavior_description'][:50]}..."
            )
        except Exception as e:
            logger.error(f"❌ 处理记录失败: {e}")

    def stop(self):
        """停止处理"""
        logger.info("🛑 停止 Event Processor...")
        self.running = False
        self.writer.close()
        logger.info("✅ 已停止")


def main():
    """主函数"""
    logger.info("="*60)
    logger.info("Event Processor - 用户行为分析处理器（本地测试版）")
    logger.info("="*60)
    logger.info(f"Kinesis Stream: {KINESIS_STREAM_NAME}")
    logger.info(f"AWS Endpoint: {AWS_ENDPOINT}")
    logger.info(f"LLM配置: {os.getenv('LLM_MODEL', '未配置（使用规则引擎）')}")
    logger.info("="*60)
    logger.info("")
    logger.info("💡 提示：生产环境请使用 lambda_handler.py")
    logger.info("")

    processor = EventProcessor()
    processor.start()


if __name__ == '__main__':
    main()
